﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using PagSeguro.Mvc.Extensions;
using PagSeguro.Mvc.Recursos;

namespace PagSeguro.Mvc
{
    /// <summary>
    /// Dados do produto vendido.
    /// </summary>
    public class Produto
    {
        #region PROPRIEDADES

        /// <summary>
        /// Get do código do produto.
        /// </summary>
        /// <remarks>
        /// ProdID_x
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 100
        /// DESCRIÇÃO.: ID do produto.
        /// </remarks>
        public string Id { get; private set; }

        /// <summary>
        /// Get da descrição do produto.
        /// </summary>
        /// <remarks>
        /// ProdDescricao_x
        /// TIPO......: Alfa-numérico
        /// TAMANHO...: 100
        /// DESCRIÇÃO.: Descrição do produto.
        /// </remarks>
        public string Descricao { get; private set; }

        /// <summary>
        /// Get do valor do produto.
        /// </summary>
        /// <remarks>
        /// ProdValor_x
        /// TIPO......: Decimal
        /// TAMANHO...: 10,2
        /// DESCRIÇÃO.: Valor unitário do produto.
        /// </remarks>
        public decimal ValorUnitario { get; private set; }

        /// <summary>
        /// Get da quantidade do produto.
        /// </summary>
        /// <remarks>
        /// ProdQuantidade_x
        /// TIPO......: Int32
        /// TAMANHO...: 10,2
        /// DESCRIÇÃO.: Quantidade comprada do produto.
        /// </remarks>
        public int QuantidadeComprada { get; private set; }

        /// <summary>
        /// Get do valor do frete do produto.
        /// </summary>
        /// <remarks>
        /// ProdFrete_x
        /// TIPO......: Decimal
        /// TAMANHO...: 10,2
        /// DESCRIÇÃO.: Valor do frete deste produto.
        ///             Formato: 0,00
        /// </remarks>
        public decimal ValorDoFrete { get; private set; }

        /// <summary>
        /// Get do preço total do produto. (Quantidade x Valor Unitário) + Valor do Frete.
        /// </summary>
        public decimal PrecoTotal 
        {
            get { return ((QuantidadeComprada * ValorUnitario) + ValorDoFrete); }
        }

        /// <summary>
        /// Get do preço total do produto sem o valor do frete. (Quantidade x Valor Unitário).
        /// </summary>
        public decimal PrecoTotalSemFrete
        {
            get { return (QuantidadeComprada * ValorUnitario); }
        }

        #endregion

        /// <summary>
        /// Construtor privado.
        /// </summary>
        /// <param name="numeroItem">Número do item.</param>
        /// <param name="dados">Dados do produto.</param>
        private Produto(int numeroItem, NameValueCollection dados) 
        {
            // TODO: Validação das chaves comentadas temporariamente
            //ValidarDadosPost(dados, numeroItem);

            this.Id = dados[Constantes.PROD_ID + numeroItem];
            this.Descricao = dados[Constantes.PROD_DESCRICAO + numeroItem];
            this.ValorUnitario = dados[Constantes.PROD_VALOR + numeroItem].ToDecimal();
            this.QuantidadeComprada = dados[Constantes.PROD_QUANTIDADE + numeroItem].ToInt32();
            this.ValorDoFrete = dados[Constantes.PROD_FRETE + numeroItem].ToDecimal();
        }

        /// <summary>
        /// Cria a coleção com os dados dos produtos vendidos.
        /// </summary>
        /// <param name="dados">Dados dos produtos.</param>
        /// <returns>Coleção dos produtos vendidos.</returns>
        public static List<Produto> MontarProdutos(NameValueCollection dados)
        {
            // TODO: Validação das chaves comentadas temporariamente
            //dados.Validar(Constantes.NUM_ITENS);

            var produtos = new List<Produto>();
            var numeroDeItens = (dados[Constantes.NUM_ITENS].ToInt32() + 1);

            for (int contProdutos = 1; contProdutos < numeroDeItens; contProdutos++)
                produtos.Add(new Produto(contProdutos, dados));

            return produtos;
        }

        /// <summary>
        /// Valida as chaves do dicionário
        /// </summary>
        /// <param name="dados">Dados dos produtos</param>
        /// <param name="numeroItem">Número do item.</param>
        private static void ValidarDadosPost(NameValueCollection dados, int numeroItem)
        {
            dados.Validar(Constantes.PROD_ID + numeroItem);
            dados.Validar(Constantes.PROD_DESCRICAO + numeroItem);
            dados.Validar(Constantes.PROD_VALOR + numeroItem);
            dados.Validar(Constantes.PROD_QUANTIDADE + numeroItem);
            dados.Validar(Constantes.PROD_FRETE + numeroItem);
        }

        /// <summary>
        /// Informações sobre o produto.
        /// </summary>
        /// <returns>Informações sobre o produto.</returns>
        public override string ToString()
        {
            return 
                String.Format(
                "Item: {0}; Valor Unitário: {1:C}; Frete: {2:C}; Quantidade: {3}; Total + Frete: {4:C}", 
                Descricao, 
                ValorUnitario, 
                ValorDoFrete,
                QuantidadeComprada,
                PrecoTotal);
        }
    }
}